package san.java.day09;

import san.java.inherit_07.Person;

/**
 * 初始化块:
 *  初始化块的作用:
 *      1. 对java对象进行初始化
 *      2. 在实际的开发中,static静态代码块用在初始化类的静态属性
 *      3. 静态代码块用在匿名内部器中代替构造器函数
 *
 *  非静态代码块: 没有static修饰的代码块
 *      1. 可以有输出语句
 *      2. 可以对类的属性声明进行初始化操作
 *      3. 可以调用静态和非静态的变量或方法
 *      4. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行.
 *      5. 每次创建对象的时候,都会执行一次.且先于构造器执行.
 *
 *  静态代码块: static修饰的代码块
 *      1. 可以有输出语句
 *      2. 可以对类的属性声明进行初始化.即: 不可以调用非静态的属性和方法
 *      3. 只能使用静态成员
 *      4. 先于非静态代码块
 *      5. 多个静态代码块按照先后顺序执行
 *      6. 静态代码块只执行一次
 *
 *  java中程序的执行过程:
 *      1. 声明成员变量的默认值
 *      2. 显示初始化, 多个初始化块依次被执行(同级别下按先后顺序执行)
 *          i  先执行静态代码块
 *          ii 在执行非静态代码块
 *      3. 构造器对成员进行赋值操作
 *
 *  注意:
 *      1. 静态代码块只执行一次
 *      2. 先执行静态代码块,再执行非静态代码块,再执行构造器
 */

public class InitBlock_01 {

    String name;
    static int age;

    // 匿名内部类
    Person p = new Person() {  // Person的匿名子类
        // 在匿名内部类中无法使用构造器

        // 匿名内部类,使用代码块代替构造方法
        {
            super.setName("lisi");
        }

        @Override
        public void work() {
            System.out.println("匿名内部类的work方法");
            System.out.println(this.getName());
        }
    };

    public InitBlock_01() {
        this.name = "san";
        System.out.println("执行的是构造器");
    }

    public static int getAge() {
        return age;
    }

    public void addAge() {
        age++;
    }

    /**
     * 非静态代码块
     */
    {
        System.out.println("执行的是非静态代码块");
    }

    /**
     * 静态代码块
     */
    static {
        age = 26;
        System.out.println("执行的是静态代码块, age = " + age);
    }

    public static void main(String[] args) {
        InitBlock_01 initBlock_01 = new InitBlock_01();
        System.out.println(InitBlock_01.getAge());
        initBlock_01.addAge();
        initBlock_01.addAge();
        initBlock_01.addAge();
        initBlock_01.addAge();
        InitBlock_01 initBlock_02 = new InitBlock_01();
        System.out.println(InitBlock_01.getAge());
        InitBlock_01 initBlock_03 = new InitBlock_01();
        InitBlock_01 initBlock_04 = new InitBlock_01();
        InitBlock_01 initBlock_05 = new InitBlock_01();

        initBlock_01.p.work();
    }

}
